package com.yuyou.weixin.controller;


import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.google.common.base.Splitter;
import com.yuyou.weixin.bean.ReturnResult;
import com.yuyou.weixin.common.WexinException;
import com.yuyou.weixin.entity.AnswerHis;
import com.yuyou.weixin.entity.TestResult;
import com.yuyou.weixin.service.IAnswerService;
import com.yuyou.weixin.util.BeanUtils;
import com.yuyou.weixin.util.WeixinUtil;
import com.yuyou.weixin.vo.AnswerVo;
import com.yuyou.weixin.vo.SubjectScoreVo;
import com.yuyou.weixin.vo.SubjectSuggestVo;
import com.yuyou.weixin.vo.TestResultVo;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

/**
 * @Author: weiwenfeng
 * @Date: 2018/6/14
 */
@RestController
@RequestMapping("/api/user")
public class UserController {
    private static final String WX_APPID = "wx0159f619d372dcc5";
    private static final String WX_SCRECT = "ff1f8cec3295d628114e1bac0f68d101";
    private static final String SCOPE_USERINFO = "snsapi_login";
    private static String TOKEN_URL =
            "https://api.weixin.qq.com/sns/oauth2/access_token?appid=%s&secret=%s&code=%s&grant_type=authorization_code";
    private static String USERINFO_URL =
            "https://api.weixin.qq.com/sns/userinfo?access_token=%s&openid=%s&lang=zh_CN";
    private static String OAUTH2_URL =
            "https://open.weixin.qq.com/connect/oauth2/authorize?appid=%s&redirect_uri=%s&response_type=code&scope=%s&state=STATE#wechat_redirect";
    private static final String DOMAIN = "http://wx.yuyou100.com";

    @Resource
    private IAnswerService answerService;

    @ApiOperation("提交结果")
    @RequestMapping(value = "/commit", method = {RequestMethod.GET, RequestMethod.POST})
    @ResponseBody
    public ReturnResult<List<TestResultVo>> commit(@RequestParam("answerString")String answerString) throws Exception {
        String param = URLDecoder.decode(answerString, "UTF-8");
        AnswerVo answerVo = JSON.parseObject(param,AnswerVo.class);
        List<TestResultVo> testResultVos = new ArrayList<>();
        try {
            List<TestResult> testResults = answerService.insertAnswer(answerVo);
            for (TestResult testResult : testResults) {
                TestResultVo testResultVo = new TestResultVo();
                BeanUtils.copyProperties(testResultVo, testResult);
                setMajorInfo(testResultVo);
                setSubjectInfo(testResultVo);
                setSubjectScore(testResultVo);
                testResultVos.add(testResultVo);
            }
        } catch (Exception e) {
            throw new WexinException(e);
        }
        return ReturnResult.success(testResultVos);
    }

    private void setSubjectScore(TestResultVo testResultVo) {
        List<SubjectScoreVo> subjectScoreVos = new ArrayList<>();
        String subjectScore = testResultVo.getSubjectScoreJson();
        JSONArray jsonArray = JSONArray.parseArray(subjectScore);
        List<JSONObject> jsonObjects = jsonArray.toJavaList(JSONObject.class);
        for (JSONObject jsonObject : jsonObjects) {
            SubjectScoreVo subjectScoreVo = new SubjectScoreVo();
            subjectScoreVo.setSubject((String) jsonObject.get("subject"));
            BigDecimal weight = (BigDecimal) jsonObject.get("weight");
            subjectScoreVo.setScore(weight.floatValue());
            subjectScoreVos.add(subjectScoreVo);
        }
        testResultVo.setSubjectScoreVos(subjectScoreVos);
    }

    private void setMajorInfo(TestResultVo testResultVo) {
        String content = WeixinUtil.getStringFromFile("university.json");
        JSONArray jsonArray = JSONArray.parseArray(content);
        String job = testResultVo.getJob();
        List<JSONObject> jsonObjects = jsonArray.toJavaList(JSONObject.class);
        for (JSONObject jsonObject : jsonObjects) {
            String jsonJob = (String) jsonObject.get("职业");
            if (job.indexOf(jsonJob) != -1) {
                testResultVo.setMajor((String) jsonObject.get("匹配专业"));
                testResultVo.setMajorBrief((String) jsonObject.get("简介"));
                String university = (String) jsonObject.get("优选学校");
                String[] univerSities = university.split(",");
                testResultVo.setUniversitys(Arrays.asList(univerSities));
            }
        }
    }

    private void setSubjectInfo(TestResultVo testResultVo) {
        String content = WeixinUtil.getStringFromFile("subject.json");
        JSONObject subjectJson = JSONObject.parseObject(content);
        List<SubjectSuggestVo> subjectSuggestVos = new ArrayList<>();
        String subjectStr = testResultVo.getSubjectComb();
        String[] subjects = subjectStr.split("\\+");
        for (String subject : subjects) {
            SubjectSuggestVo suggestVo = new SubjectSuggestVo();
            String suggestion = (String) subjectJson.get(subject);
            suggestVo.setSubject(subject);
            suggestVo.setSuggestion(suggestion);
            subjectSuggestVos.add(suggestVo);
        }
        testResultVo.setSubjectSuggestVos(subjectSuggestVos);
    }

    @ApiOperation("查询用户测试历史")
    @RequestMapping(value = "/queryHis", method = {RequestMethod.GET, RequestMethod.POST})
    @ResponseBody
    public ReturnResult<List<AnswerHis>> queryHis(@RequestParam("unionid") String unionid) {
        List<AnswerHis> answerHis = answerService.queryAnswerHis(unionid);
        return ReturnResult.success(answerHis);
    }

    @ApiOperation("用户登录")
    public void authorizedLoginUrl(@RequestParam("redirectUrl") String redirectUrl, HttpServletResponse response) throws Exception {
        String myUrl = "/weixinRedirect";
        try {
            //拼接微信回调地址
            myUrl = java.net.URLEncoder.encode(myUrl, "utf-8");
        } catch (UnsupportedEncodingException e) {
            throw new WexinException(e);
        }
        OAUTH2_URL = String.format(OAUTH2_URL, WX_APPID, myUrl, SCOPE_USERINFO);
        WeixinUtil.httpRequest(OAUTH2_URL, "GET", null);
        response.sendRedirect(DOMAIN + redirectUrl);
    }

    public void weixinRedirect(HttpServletRequest request, HttpServletResponse response) {
        String weixinRedirectUrl = request.getRequestURL().toString();
        String code = getPara(weixinRedirectUrl, "code");
        TOKEN_URL = String.format(TOKEN_URL, WX_APPID, WX_SCRECT, code);
        String responseStr = WeixinUtil.httpRequest(TOKEN_URL, "GET", null);
        JSONObject jsonObject = JSON.parseObject(responseStr);
        if (null != jsonObject.getString("errcode")) {
            throw new WexinException("获取token失败," + jsonObject.getString("errcode") + ","
                    + jsonObject.getString("errmsg"));
        } else {
            String accessToken = jsonObject.getString("access_token");
            String openId = jsonObject.getString("openid");
            // 使用获取到的 Access_token 和 openid 拉取用户信息
            USERINFO_URL = String.format(USERINFO_URL, accessToken, openId);
            // 通过https方式请求获得用户信息响应
            String userMessageResponse = WeixinUtil.httpRequest(USERINFO_URL, "GET", null);
            JSONObject userJsonObject = JSON.parseObject(userMessageResponse);
            if (null != userJsonObject.getString("errcode")) {
                throw new WexinException("获取用户信息失败," + userJsonObject.getString("errcode") + ","
                        + userJsonObject.getString("errmsg"));
            } else {
                convertUserInfo(response, userJsonObject);
            }
        }
    }

    private String getPara(String url, String name) {
        String params = url.substring(url.indexOf("?") + 1, url.length());
        Map<String, String> split = Splitter.on("&").withKeyValueSeparator("=").split(params);
        return split.get(name);
    }

    private void convertUserInfo(HttpServletResponse response, JSONObject userJsonObject) {
        try {
            //用户昵称
            String nickName = userJsonObject.getString("nickname");
            //用户性别
            String sex = userJsonObject.getString("sex");
            sex = (sex.equals("1")) ? "男" : "女";
            //用户唯一标识
            String openid = userJsonObject.getString("openid");
            response.setHeader("nickName", nickName);
            response.setHeader("sex", sex);
            response.setHeader("openid", openid);
        } catch (Exception e) {
            throw new WexinException(e);
        }
    }
}
